
<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
      <title>5.9.&nbsp;私有函数</title>
      <link rel="stylesheet" href="../diveintopython.css" type="text/css">
      <link rev="made" href="mailto:f8dy@diveintopython.org">
      <meta name="generator" content="DocBook XSL Stylesheets V1.52.2">
      <meta name="keywords" content="Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free">
      <meta name="description" content="Python from novice to pro">
      <link rel="home" href="../toc/index.html" title="Dive Into Python">
      <link rel="up" href="index.html" title="第&nbsp;5&nbsp;章&nbsp;对象和面向对象">
      <link rel="previous" href="class_attributes.html" title="5.8.&nbsp;类属性介绍">
      <link rel="next" href="summary.html" title="5.10.&nbsp;小结">
   </head>
   <body>
      <table id="Header" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td id="breadcrumb" colspan="5" align="left" valign="top">导航：<a href="../index.html">起始页</a>&nbsp;&gt;&nbsp;<a href="../toc/index.html">Dive Into Python</a>&nbsp;&gt;&nbsp;<a href="index.html">对象和面向对象</a>&nbsp;&gt;&nbsp;<span class="thispage">私有函数</span></td>
            <td id="navigation" align="right" valign="top">&nbsp;&nbsp;&nbsp;<a href="class_attributes.html" title="上一页: “类属性介绍”">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;<a href="summary.html" title="下一页: “小结”">&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3" id="logocontainer">
               <h1 id="logo"><a href="../index.html" accesskey="1">深入 Python :Dive Into Python 中文版</a></h1>
               <p id="tagline">Python 从新手到专家 [Dip_5.4b_CPyUG_Release]</p>
            </td>
            <td colspan="3" align="right">
               <form id="search" method="GET" action="http://www.google.com/custom">
                  <p><label for="q" accesskey="4">Find:&nbsp;</label><input type="text" id="q" name="q" size="20" maxlength="255" value=""> <input type="submit" value="搜索"><input type="hidden" name="domains" value="woodpecker.org.cn/diveintopython"><input type="hidden" name="sitesearch" value="www.woodpecker.org.cn/diveintopython"></p>
               </form>
            </td>
         </tr>
      </table>
      <!--#include virtual="/inc/ads" -->
      <div class="section" lang="zh_cn">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="fileinfo.private"></a>5.9.&nbsp;私有函数
                  </h2>
               </div>
            </div>
            <div></div>
         </div>
         <p>与大多数语言一样，<span class="application">Python</span> 也有私有的概念：
         </p>
         <div class="itemizedlist">
            <ul>
               <li>私有函数不可以从它们的模块外面被调用</li>
               <li>私有类方法不能够从它们的类外面被调用</li>
               <li>私有属性不能够从它们的类外面被访问</li>
            </ul>
         </div>
         <div class="abstract">
            <p>与大多数的语言不同，一个 <span class="application">Python</span> 函数，方法，或属性是私有还是公有，完全取决于它的名字。
            </p>
         </div>
         <p>如果一个 <span class="application">Python</span> 函数，类方法，或属性的名字以两个下划线开始 (但不是结束)，它是私有的；其它所有的都是公有的。
            <span class="application">Python</span> 没有类方法<span class="emphasis"><em>保护</em></span> 的概念 (只能用于它们自已的类和子类中)。类方法或者是私有 (只能在它们自已的类中使用) 或者是公有 (任何地方都可使用)。
         </p>
         <p>在 <tt class="classname">MP3FileInfo</tt> 中，有两个方法：<tt class="function">__parse</tt> 和 <tt class="function">__setitem__</tt>。正如我们已经讨论过的，<tt class="function">__setitem__</tt> 是一个<a href="special_class_methods.html#fileinfo.specialmethods.setitem.example" title="例&nbsp;5.13.&nbsp;__setitem__ 专用方法">专有方法</a>；通常，你不直接调用它，而是通过在一个类上使用字典语法来调用，但它是公有的，并且如果有一个真正好的理由，你可以直接调用它 (甚至从 <tt class="filename">fileinfo</tt> 模块的外面)。然而，<tt class="function">__parse</tt> 是私有的，因为在它的名字前面有两个下划线。
         </p><a name="tip.specialmethodnames"></a><table class="note" border="0" summary="">
            <tr>
               <td rowspan="2" align="center" valign="top" width="1%"><img src="../images/note.png" alt="注意" title="" width="24" height="24"></td>
            </tr>
            <tr>
               <td colspan="2" align="left" valign="top" width="99%">在 <span class="application">Python</span> 中，所有的专用方法 (像 <a href="special_class_methods.html#fileinfo.specialmethods.setitem.example" title="例&nbsp;5.13.&nbsp;__setitem__ 专用方法"><tt class="function">__setitem__</tt></a>) 和内置属性 (像 <a href="../getting_to_know_python/everything_is_an_object.html#odbchelper.import" title="例&nbsp;2.3.&nbsp;访问 buildConnectionString 函数的 doc string"><tt class="literal">__doc__</tt></a>) 遵守一个标准的命名习惯：开始和结束都有两个下划线。不要对你自已的方法和属性用这种方法命名；到最后，它只会把你 (或其它人) 搞乱。
               </td>
            </tr>
         </table>
         <div class="example"><a name="d0e14144"></a><h3 class="title">例&nbsp;5.19.&nbsp;尝试调用一个私有方法</h3><pre class="screen"><tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>import</span> fileinfo</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">m = fileinfo.MP3FileInfo()</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">m.__parse(<span class='pystring'>"/music/_singles/kairo.mp3"</span>)</span> <a name="fileinfo.private.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<span class="traceback">Traceback (innermost last):
  File "&lt;interactive input&gt;", line 1, in ?
AttributeError: 'MP3FileInfo' instance has no attribute '__parse'</span></pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#fileinfo.private.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">如果你试图调用一个私有方法，<span class="application">Python</span> 将引发一个有些误导的异常，宣称那个方法不存在。当然它确实存在，但是它是私有的，所以在类外是不可使用的。严格地说，私有方法在它们的类外是可以访问的，只是不<span class="emphasis"><em>容易</em></span> 处理。在 <span class="application">Python</span> 中没有什么是真正私有的；在内部，私有方法和属性的名字被忽然改变和恢复，以致于使得它们看上去用它们给定的名字是无法使用的。你可以通过 <tt class="function">_MP3FileInfo__parse</tt> 名字来使用 <tt class="classname">MP3FileInfo</tt> 类的 <tt class="function">__parse</tt> 方法。知道了这个方法很有趣，然后要保证决不在真正的代码中使用它。私有方法由于某种原因而私有，但是像其它很多在 <span class="application">Python</span> 中的东西一样，它们的私有化基本上是习惯问题，而不是强迫的。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <div class="furtherreading">
            <h3>进一步阅读</h3>
            <ul>
               <li><a href="http://www.python.org/doc/current/tut/tut.html"><i class="citetitle"><span class="application">Python</span> Tutorial</i></a> 讨论了<a href="http://www.python.org/doc/current/tut/node11.html#SECTION0011600000000000000000">私有变量</a>的内部工作方式。
               </li>
            </ul>
         </div>
      </div>
      <table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td width="35%" align="left"><br><a class="NavigationArrow" href="class_attributes.html">&lt;&lt;&nbsp;类属性介绍</a></td>
            <td width="30%" align="center"><br>&nbsp;<span class="divider">|</span>&nbsp;<a href="index.html#fileinfo.divein" title="5.1.&nbsp;概览">1</a> <span class="divider">|</span> <a href="importing_modules.html" title="5.2.&nbsp;使用 from module import 导入模块">2</a> <span class="divider">|</span> <a href="defining_classes.html" title="5.3.&nbsp;类的定义">3</a> <span class="divider">|</span> <a href="instantiating_classes.html" title="5.4.&nbsp;类的实例化">4</a> <span class="divider">|</span> <a href="userdict.html" title="5.5.&nbsp;探索 UserDict：一个封装类">5</a> <span class="divider">|</span> <a href="special_class_methods.html" title="5.6.&nbsp;专用类方法">6</a> <span class="divider">|</span> <a href="special_class_methods2.html" title="5.7.&nbsp;高级专用类方法">7</a> <span class="divider">|</span> <a href="class_attributes.html" title="5.8.&nbsp;类属性介绍">8</a> <span class="divider">|</span> <span class="thispage">9</span> <span class="divider">|</span> <a href="summary.html" title="5.10.&nbsp;小结">10</a>&nbsp;<span class="divider">|</span>&nbsp;
            </td>
            <td width="35%" align="right"><br><a class="NavigationArrow" href="summary.html">小结&nbsp;&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3"><br></td>
         </tr>
      </table>
      <div class="Footer">
         <p class="copyright">Copyright © 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
         <p class="copyright">Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007 <a href="mailto:python-cn@googlegroups.com">CPyUG (邮件列表)</a></p>
      </div>
   </body>
</html>